package xyz.yuzegod.megawalls.game;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;

import java.util.ArrayList;
import java.util.List;

public class GameWall
{
    private Location minCorner;
    private Location maxCorner;
    private World world;
    private List<Block> blocks;
    private boolean falldown;
    
    public GameWall(final Location pos1, final Location pos2) {
        this.minCorner = null;
        this.maxCorner = null;
        this.world = null;
        this.blocks = new ArrayList<Block>();
        this.falldown = false;
        if (pos1 == null || pos2 == null) {
            return;
        }
        if (!pos1.getWorld().getName().equals(pos2.getWorld().getName())) {
            return;
        }
        this.world = pos1.getWorld();
        this.setMinMax(pos1, pos2);
        this.loadBlocks();
    }
    
    public Location getMin() {
        return this.minCorner;
    }
    
    public Location getMax() {
        return this.maxCorner;
    }
    
    private void setMinMax(final Location pos1, final Location pos2) {
        this.minCorner = this.getMinimumCorner(pos1, pos2);
        this.maxCorner = this.getMaximumCorner(pos1, pos2);
    }
    
    private Location getMinimumCorner(final Location pos1, final Location pos2) {
        return new Location(this.world, (double)Math.min(pos1.getBlockX(), pos2.getBlockX()), (double)Math.min(pos1.getBlockY(), pos2.getBlockY()), (double)Math.min(pos1.getBlockZ(), pos2.getBlockZ()));
    }
    
    private Location getMaximumCorner(final Location pos1, final Location pos2) {
        return new Location(this.world, (double)Math.max(pos1.getBlockX(), pos2.getBlockX()), (double)Math.max(pos1.getBlockY(), pos2.getBlockY()), (double)Math.max(pos1.getBlockZ(), pos2.getBlockZ()));
    }
    
    public List<Block> getBlocks() {
        return this.blocks;
    }
    
    private void loadBlocks() {
        for (int x = this.minCorner.getBlockX(); x <= this.maxCorner.getBlockX(); ++x) {
            for (int y = this.minCorner.getBlockY(); y <= this.maxCorner.getBlockY(); ++y) {
                for (int z = this.minCorner.getBlockZ(); z <= this.maxCorner.getBlockZ(); ++z) {
                    final Location loc = new Location(this.world, (double)x, (double)y, (double)z);
                    if (loc.getBlock().getType() != Material.AIR) {
                        this.blocks.add(loc.getBlock());
                    }
                }
            }
        }
    }
    
    public boolean isInWall(final Location location) {
        return location.getWorld().equals(this.world) && location.getBlockX() >= this.minCorner.getBlockX() && location.getBlockX() <= this.maxCorner.getBlockX() && location.getBlockY() >= this.minCorner.getBlockY() && location.getBlockY() <= this.maxCorner.getBlockY() && location.getBlockZ() >= this.minCorner.getBlockZ() && location.getBlockZ() <= this.maxCorner.getBlockZ();
    }
    
    public void falldown() {
        if (this.falldown) {
            return;
        }
        this.falldown = true;
        for (final Block block : this.blocks) {
            this.world.getBlockAt(block.getLocation()).setType(Material.AIR);
        }
    }
}
